package org.acghub.mtdb.xmlgen.maker;

import org.acghub.mtdb.common.Bean;
import org.acghub.mtdb.common.Config;
import org.acghub.mtdb.core.TBean;
import org.acghub.mtdb.util.StringUtil;
import org.acghub.mtdb.xmlgen.Maker;
import org.acghub.mtdb.xmlgen.maker.bean.*;
import org.acghub.mtdb.xmlgen.visitor.VarDeclareVisitor;
import org.acghub.mtdb.xmlgen.visitor.VarGetterVisitor;
import org.acghub.mtdb.xmlgen.visitor.VarSetterVisitor;

import java.io.PrintStream;

/**
 * @author zhouhe
 */
public class BeanMaker extends Maker<Bean> {


    public BeanMaker(Bean bean, Config config) {
        super(bean, config);
    }

    @Override
    public void make() throws Exception {
        try (PrintStream ps = this.config().openBeanFile(this.inner().getName())) {
            this.make0(ps);
        }
    }

    private void make0(PrintStream ps) throws Exception {
        String packageName = this.config().beanFullPackage();
        String baseClassName = TBean.class.getCanonicalName();
        String className = StringUtil.upperFirstChar(this.inner().getName());
        // 0.包声明
        ps.println("package " + packageName + ";");
        ps.println();
        ps.println("/**");
        ps.println("* xmlgen自动生成，不要修改此文件！！！");
        ps.println("*/");
        ps.println("public final class " + className + " extends " + baseClassName + " {");

        // 1.字段声明
        this.inner().getVars().forEach(var -> var.accept(new VarDeclareVisitor(var, ps, StringUtil.TAB)));

        // 2.Constructor
        new BeanConstructorMaker(this.inner(), this.config(), ps, StringUtil.TAB).make();

        // 3.onConstructor函数
        new BeanOnConstructorMaker(this.inner(), this.config(), ps, StringUtil.TAB).make();

        // 4.getter setter
        this.inner().getVars().forEach(var -> var.accept(new VarGetterVisitor(var, ps, StringUtil.TAB)));
        this.inner().getVars().forEach(var -> var.accept(new VarSetterVisitor(var, ps, StringUtil.TAB)));

        // 5.marshal unmarshal
        BeanMarshalMaker.make(this.inner(), this.config(), ps, StringUtil.TAB);

        // 6.hashcode
        new BeanHashCodeMaker(this.inner(), this.config(), ps, StringUtil.TAB).make();

        // 7.equals
        new BeanEqualsMaker(this.inner(), this.config(), ps, StringUtil.TAB).make();

        // 8.toString
        new BeanToStringMaker(this.inner(), this.config(), ps, StringUtil.TAB).make();

        ps.println("}");
        ps.println();
    }
}
